'use strict';

const Olt = require('./OLT');
const snmp = require('net-snmp');
const {createSession} = require('../RZtelnet/CreateSession');
const RzTelnet = require('../RZtelnet');
const common = require('../common');
const {parseOltProfile,strToEachType,parseOnuWan,parseEth} = require('./common');
const fs = require('fs');
const path = require('path');
const { resolve } = require('path');
class ZTEOLT extends Olt {
  constructor(options) {
    super(options);
  }
  // 获取ontStatus
  async ZTETestConnection(me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = `${this.options.ip}:${this.options.tPort}`;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      const fn = function(message) {
        if (message.indexOf('Error') != -1) {
          return {
            result: false,
            message,
          };
        } else if (message.indexOf('No username or bad password') != -1) {
          return {
            result: false,
            message,
          };
        } else if (message.indexOf('Bad password') != -1) {
          return {
            result: false,
            message,
          };
        }
        return {
          result: true,
          message: '',
        };
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_VERSION',
            oltHardVersion: 'NONE',
            view,
          },
          fn,
          me
        );
        if (
          resultArr.length > 0 &&
          (resultArr[0].indexOf('Error') != -1 ||
            resultArr[0].indexOf('No username or bad password') != -1 ||
            resultArr[0].indexOf('Bad password') != -1)
        ) {
          return resolve(false);
        }
        resolve(true);
      } catch (error) {
        resolve(false);
      }
    });
  }
  // SNMP获取systemName
  async getOltSystemName(ctx) {
    return new Promise(async (resolve, reject) => {
      const olt = {
        systemName: '',
        runningTime: '',
      };
      const oids = [
        '1.3.6.1.2.1.1.5.0', // systemName
        '1.3.6.1.2.1.1.3.0', // running time
      ];
      const session = await createSession.call({ctx,
        proxyFlag : this.options.proxyFlag},this.options.ip,this.options.community,this.options);
      session.get(oids, function(error, varbinds) {
        if (error) {
          reject(error);
        } else {
          for (let i = 0; i < varbinds.length; i++) {
            if (!snmp.isVarbindError(varbinds[i])) {
              if (varbinds[i].oid == oids[0]) {
                olt.systemName = varbinds[i].value.toString();
              }
              if (varbinds[i].oid == oids[1]) {
                olt.runningTime = varbinds[i].value.toString();
              }
            }
          }
          resolve(olt);
        }
        session.close();
      });
    });
  }
  // 设置 RZAdmin
  async setRZAdmin(me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CREATE_RZADMIN',
            oltHardVersion: 'NONE',
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取Version
  async getOltVersion(me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        //调用
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_VERSION',
            oltHardVersion: 'NONE',
            view,
          },
          null,
          me
        );
        // 解析返回字符串
        const result = {
          oltHardVersion:"",
          oltHardwareVersion:"",
          oltSoftwareVersion:"",
          MCIndex:"",
        };
        const reg = /(C\d{3}).*(V\d.\d.\d)/;
        const arr1 = reg.exec(resultArr[0].split('\n')[0]);
        const arr2 = reg.exec(resultArr[0].split('\n')[2]);
        if(arr1){
          result.oltHardVersion = arr1[1] + ' ' + arr1[2];
          result.oltHardwareVersion = arr1[1];
          result.oltSoftwareVersion = arr1[2];
          result.MCIndex = "";
        }else if(arr2){
          result.oltHardVersion = arr2[1] + ' ' + arr2[2];
          result.oltHardwareVersion = arr2[1];
          result.oltSoftwareVersion = arr2[2];
          result.MCIndex = "";
        }
        resolve(result);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取oltInformation
  async getOltInformation(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_OLTINFORMATION',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const result = {};
        const msg1 = resultArr[0];
        const msg2 = resultArr[1];
        result.MCIndex = msg1
          .substring(msg1.indexOf('Position') + 8, msg1.indexOf('Type'))
          .replace(':', '')
          .trim()
          .split('/')[2];
        result.cpuUsage = msg1
          .substring(
            msg1.indexOf('CPU Usage') + 9,
            msg1.indexOf('Memory Usage')
          )
          .replace(':', '')
          .trim();
        result.memoryUsage = msg1
          .substring(
            msg1.indexOf('Memory Usage') + 12,
            msg1.indexOf('Serial Number')
          )
          .replace(':', '')
          .trim();
        if(oltHardVersion.indexOf('V1.2.5') != -1 ){
          result.systemTime = msg2.split('\n')[1].replace('\r', '');
        }else if(oltHardVersion.indexOf('V2.1.0') != -1){
          result.systemTime = msg2.split('\n')[0].replace('\r', '');
        }
        resolve(result);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取oltTemperature
  async getOltTemperature(oltHardVersion, MCIndex, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        MCIndex
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_OLTTEMPERATURE',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        console.log(resultArr)
        var oltTemperature
        if(oltHardVersion.indexOf('V1.2.5') != -1){
          const msg = resultArr[0];
          const a = msg.substring(msg.indexOf(MCIndex));
          oltTemperature = a
            .substring(0, a.indexOf('\n'))
            .replace(/\s+/g, '|')
            .split('|')[1];
        }else if(oltHardVersion.indexOf('V2.1.0') != -1){
          oltTemperature = resultArr[0].split('\n')[4].replace(/\s{2,}/g,'|').split('|')[3]
        }
        resolve(oltTemperature);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取cardInformation
  async getCardInformation(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_CARDINFORMATION',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const lines = msg.split('\n');
        const titleArray = [
          'Rack',
          'Shelf',
          'Slot',
          'CfgType',
          'RealType',
          'Port',
          'HardVer',
          'SoftVer',
          'Status',
        ];
        const colInfo = [];
        const title = lines.filter(
          value => value.indexOf(titleArray[0]) != -1
        );
        titleArray.forEach(titleItem => {
          colInfo.push(title[0].indexOf(titleItem));
        });
        const contents = lines.filter(value => {
          const result =
            value.indexOf('---') == -1 &&
            value.indexOf('show card') == -1 &&
            value.indexOf(titleArray[0]) == -1 &&
            value.indexOf('config') == -1;
          return result;
        });
        const arr = [];
        contents.forEach(item => {
          const obj = new Object();
          obj[titleArray[0]] = item.substring(colInfo[0], colInfo[1]);
          obj[titleArray[1]] = item.substring(colInfo[1], colInfo[2]);
          obj[titleArray[2]] = item.substring(colInfo[2], colInfo[3]);
          obj[titleArray[3]] = item.substring(colInfo[3], colInfo[4]);
          obj[titleArray[4]] = item.substring(colInfo[4], colInfo[5]);
          obj[titleArray[5]] = item.substring(colInfo[5], colInfo[6]);
          obj[titleArray[6]] = item.substring(colInfo[6], colInfo[7]);
          obj[titleArray[7]] = item.substring(colInfo[7], colInfo[8]);
          obj[titleArray[8]] = item.substr(colInfo[8]);
          arr.push({
            slot: obj[titleArray[2]].trim(),
            type: obj[titleArray[3]].trim(),
            realType: obj[titleArray[4]].trim(),
            port: obj[titleArray[5]].trim(),
            sw: obj[titleArray[7]].trim(),
            status: obj[titleArray[8]].trim(),
          });
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取ponport和uplinkport
  async getPonPortsAndUplinkPorts(ctx) {
    const maxRepetitions = 20;
    const oid1 = '1.3.6.1.2.1.31.1.1';
    const columns1 = [ 1 ];
    const oid2 = '1.3.6.1.2.1.2.2';
    const columns2 = [ 5, 7, 8 ];
    const p1 = new Promise(async (resolve, reject) => {
      const session = await createSession.call({ctx,
        proxyFlag : this.options.proxyFlag},this.options.ip,this.options.community,this.options);
      session.tableColumns(
        oid1,
        columns1,
        maxRepetitions,
        function(error, table) {
          if (error) {
            return reject(error);
          }
          return resolve(table);
        }
      );
    });
    const p2 = new Promise(async (resolve, reject) => {
      const session = await createSession.call({ctx,
        proxyFlag : this.options.proxyFlag},this.options.ip,this.options.community,this.options);
      session.tableColumns(
        oid2,
        columns2,
        maxRepetitions,
        function(error, table) {
          if (error) {
            return reject(error);
          }
          return resolve(table);
        }
      );
    });
    return Promise.all([ p1, p2 ]);
  }
  // 获取OnuProfile列表
  async getOnuProfileList(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_ONUPROFILELIST',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const resultArray = [];
        if(oltHardVersion.indexOf('V1.2.5') != -1){
          const arr = msg.split('Onu type name');
          arr.shift();
          arr.forEach(item => {
            resultArray.push({
              Pname: item.split('\n')[0].split(':')[1].trim(),
            });
          });
        }else if(oltHardVersion.indexOf('V2.1.0') != -1){
          const arr = msg.split('ONU type name');
          arr.shift();
          arr.forEach(item => {
            resultArray.push({
              Pname: item.split('\n')[0].split(':')[1].trim(),
            });
          });
        }
        resolve(resultArray);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取DBAProfile列表
  async getDBAProfileList(oltHardVersion, me) {
    // 中兴需要获取tcountprofile,供onu使用
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_DBAPROFILELIST',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const resultArray = [];
        var strArr
        // if(oltHardVersion.indexOf('V1.2.5') != -1){
        //   strArr = msg.split('Name');
        // }else if(oltHardVersion.indexOf('V2.1.0') != -1){
        //   strArr = msg.split('name');
        // }
        strArr = msg.split(/name/i);
        strArr.shift();
        strArr.forEach((item, index) => {
          const arr = item.split('\n');
          const name = arr[0].split(':')[1].trim();
          const type = arr[2].replace(/\s{2,}/g, '|').split('|')[0].trim();
          const fbw = arr[2].replace(/\s{2,}/g, '|').split('|')[1].trim();
          const abw = arr[2].replace(/\s{2,}/g, '|').split('|')[2].trim();
          const max = arr[2].replace(/\s{2,}/g, '|').split('|')[3].trim();
          resultArray.push({
            name,
            max,
            type,
            fbw,
            abw,
          });
        });
        resolve(resultArray);
      } catch (error) {
        reject(error);
      }
    });
  }
  async getOltRemoteProfileDetail(lineNames,oltHardVersion,me){
    return new Promise(async(resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        arr:lineNames
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_REMOTEPROFILE_DETAIL',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        let vlanREG = /service\s+(\w+)\s+gemport\s+(\w+)\s+vlan\s+(\w+)$/i
        let remoteprofileArray = new Map()
        resultArr.forEach((row,index)=>{
          let lines = row.split('\n');
          if(lines.length>0){
            let currentName = lineNames[index].name;
            lines.forEach(line=>{
              if(remoteprofileArray.has(currentName)){
                let vlanGroup = vlanREG.exec(line)
                if(vlanGroup){
                  let [str,serviceName,gemport,vlan] = vlanGroup;
                  remoteprofileArray.get(currentName).push({
                    bName:serviceName,
                    gVLAN:vlan,
                    gemport:gemport
                  })
                }      
              }else{
                let vlanGroup = vlanREG.exec(line)
                if(vlanGroup){
                let [str,serviceName,gemport,vlan] = vlanGroup;
                remoteprofileArray.set(currentName,[{
                  bName:serviceName,
                  gVLAN:vlan,
                  gemport:gemport
                }]);
                }
              }
                      
            })            
          }
        })        
        resolve(remoteprofileArray)
      }catch (error) {
        reject(error);
      }
    })
  }
  async getOltLineProfileDetail(lineNames,oltHardVersion,me){
    return new Promise(async(resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        arr:lineNames
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_LINEPROFILE_DETAIL',
            oltHardVersion,
            view,
          },
          null,
          me
        );

        let tcountDbaREG = /tcont\s+(\d+)\s+profile\s+(\w+)$/i
        let gemTcountREG = /gemport\s+(\d+)\s+.*tcont\s+(\d+)\s?.*$/i
        let speedReg = /gemport\s+(\d+)\s+traffic-limit\s+upstream\s+(\w+)\s+downstream\s+(\w+).*$/i
        let tconts = [];
        resultArr.forEach((row,index)=>{
          let lines = row.split('\n');
          if(lines.length>0){
            let bussinessTree = {}
            let gemTree={}
            let currentName = lineNames[index].name;
            lines.forEach(line=>{
              let tcountDba = tcountDbaREG.exec(line)
              if(tcountDba){
                let [str,tcont,dbaProfile] = tcountDba;
                if(!bussinessTree.hasOwnProperty(tcont)){
                  bussinessTree[tcont] = {
                    name:currentName,
                    dbaProfile,
                    gemArr:{}
                  };
                }else{
                  bussinessTree[tcont].dbaProfile=dbaProfile
                  bussinessTree[tcont].name=currentName
                }
              }
              let gemTcount = gemTcountREG.exec(line)
              if(gemTcount){
                let [str,gemport,tcont] = gemTcount;
                bussinessTree[tcont].gemArr[gemport]={
                  dbaProfile:bussinessTree[tcont].dbaProfile,
                  isSpeedLimit:false,
                  DownSpeed:'',
                  UplinkSpeed:'',
                  name:currentName,
                  tcont:tcont,
                  gemport
                };
                gemTree[gemport] = {
                  getTcont:function(){
                    return ()=>bussinessTree[tcont]
                  }
                }
              }
              let speed = speedReg.exec(line)
              if(speed){
                let [str,gemport,upstream,downstream] = speed;
                let tcont = gemTree[gemport].getTcont()()
                tcont.gemArr[gemport].isSpeedLimit=true;
                tcont.gemArr[gemport].DownSpeed=downstream;
                tcont.gemArr[gemport].UplinkSpeed=upstream;
                tcont.gemArr[gemport].name=currentName;
              }
            })
            gemTree=null;
            tconts.push(bussinessTree)
          }
        })
        let lineprofileArray = new Map();
        tconts.forEach(tcont=>{
          for(let tcontNo in tcont){
            let gem = tcont[tcontNo].gemArr
            for(let gemNo in gem){
              lineprofileArray.has(gem[gemNo].name)?lineprofileArray.get(gem[gemNo].name).push(gem[gemNo]):lineprofileArray.set(gem[gemNo].name,[gem[gemNo]])
            }
          }
        })
        resolve(lineprofileArray)
      }catch (error) {
        reject(error);
      }
    })
  }
  async getOltRemoteProfile(oltHardVersion,me){
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_REMOTEPROFILE',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const arr = [];
        if(msg.indexOf('No related information to show') != -1){
          return resolve(arr)
        }
        const lines = msg
        .replace(/\u0008/g, '')
        .replace(/\s*--More--\s*/g, '\n')
        .split('\n');
        var titleArray
        if(oltHardVersion.indexOf('V1.2.5') != -1){
          titleArray = [
            'ProfileName',
          ];
        }else if(oltHardVersion.indexOf('V2.1.0') != -1){
          titleArray = [
            'Profile name',
          ];
        }
        const colInfo = [];
        const title = lines.filter(
          value => value.indexOf(titleArray[0]) != -1
        );
        titleArray.forEach(titleItem =>
          colInfo.push(title[0].indexOf(titleItem))
        );
        const contents = lines.filter(
          value =>
            value.indexOf('---') == -1 &&
            value.indexOf('ONU Number') == -1 &&
            value.indexOf('show') == -1 &&
            value.indexOf('kbps') == -1 &&
            value.indexOf('Command') == -1 &&
            value.indexOf('Note') == -1 &&
            value.indexOf(this.options.systemName) == -1 &&
            value.indexOf('display') == -1 &&
            value.indexOf('Total') == -1 &&
            value.indexOf('config') == -1 &&
            value.indexOf(titleArray[0]) == -1 &&
            value.indexOf('>') == -1
        );
        contents.forEach(item => {
          arr.push({
            name: item.substring(colInfo[0], colInfo[1]).trim(),
          });
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  //获取lineprofile
  async getOltLineProfile(oltHardVersion,me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_LINEPROFILE',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const arr = [];
        if(msg.indexOf('No related information to show') != -1){
          return resolve(arr)
        }
        const lines = msg
        .replace(/\u0008/g, '')
        .replace(/\s*--More--\s*/g, '\n')
        .split('\n');
        var titleArray
        if(oltHardVersion.indexOf('V1.2.5') != -1){
          titleArray = [
            'ProfileName',
          ];
        }else if(oltHardVersion.indexOf('V2.1.0') != -1){
          titleArray = [
            'Profile name',
          ];
        }
        const colInfo = [];
        const title = lines.filter(
          value => value.indexOf(titleArray[0]) != -1
        );
        titleArray.forEach(titleItem =>
          colInfo.push(title[0].indexOf(titleItem))
        );
        const contents = lines.filter(
          value =>
            value.indexOf('---') == -1 &&
            value.indexOf('ONU Number') == -1 &&
            value.indexOf('show') == -1 &&
            value.indexOf('kbps') == -1 &&
            value.indexOf('Command') == -1 &&
            value.indexOf('Note') == -1 &&
            value.indexOf(this.options.systemName) == -1 &&
            value.indexOf('display') == -1 &&
            value.indexOf('Total') == -1 &&
            value.indexOf('config') == -1 &&
            value.indexOf(titleArray[0]) == -1 &&
            value.indexOf('>') == -1
        );
        contents.forEach(item => {
          arr.push({
            name: item.substring(colInfo[0], colInfo[1]).trim(),
          });
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取vlan列表
  async getOltVlan(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_VLANLIST',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const arr = [];
        const infoArr = msg.split(':');
        const vlanStrArr = infoArr[2].replace(/\n/g, '').match(/(\d*-?\d+,?)/g);
        vlanStrArr.forEach(item => {
          arr.push({
            VlanID: item.replace(',', ''),
          });
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  //获取Mac列表
  async getOltMac(oltHardVersion,me){
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_MACLIST',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const lines = msg
            .replace(/\u0008/g, '')
            .replace(/\s*--More--\s*/g, '\n')
            .split('\n');
        const titleArray = [
          'Mac address',
          'Vlan',
          'Type',
          'Port',
          'Vc',
        ];
        const colInfo = [];
        const title = lines.filter(
          value => value.indexOf(titleArray[0]) != -1
        );
        titleArray.forEach(titleItem =>
          colInfo.push(title[0].indexOf(titleItem))
        );
        const contents = lines.filter(
          value =>
            value.indexOf('---') == -1 &&
            value.indexOf('ONU Number') == -1 &&
            value.indexOf('show') == -1 &&
            value.indexOf('kbps') == -1 &&
            value.indexOf('Command') == -1 &&
            value.indexOf('Note') == -1 &&
            value.indexOf(this.options.systemName) == -1 &&
            value.indexOf('display') == -1 &&
            value.indexOf('Total') == -1 &&
            value.indexOf('config') == -1 &&
            value.indexOf(titleArray[0]) == -1 &&
            value.indexOf('>') == -1
        );
        const arr = [];
        if(oltHardVersion.indexOf('V2.1.0') != -1){
          contents.shift()
        }
        contents.forEach(item => {
          const obj = new Object();
          let result = item.replace(/\s{2,}/g,'|').split('|')
          let mac = result[0].replace(/\./g,'-')
          let vlan = result[1]
          let type = result[2]
          let port = result[3]
          let PhysicalPort 
          if(result[3].indexOf(":") != -1){
            PhysicalPort = result[3].split(':')[0]
          }else{
            PhysicalPort = result[3]
          }
          let vc = result[4]||""
          arr.push({
            port,
            mac,
            vlan,
            type,
            vc,
            PhysicalPort
          });
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取speedProfile列表
  async getOltSpeedProfile(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_SPEEDPROFILE',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const resultArray = [];
        var strArr
        if(oltHardVersion.indexOf('V1.2.5') != -1){
          strArr = msg.split('Name');
        }else if(oltHardVersion.indexOf('V2.1.0') != -1){
          strArr = msg.split('name');
        }
        strArr.shift();
        strArr.forEach(item => {
          const arr = item.split('\n');
          const name = arr[0].split(':')[1].trim();
          const result = arr[3]
            .replace(/\s*--More--\s*/g, '')
            .trim()
            .replace(/\s+/g, '|')
            .split('|');
          const SIR = result[result.length - 4];
          const PIR = result[result.length - 3];
          const CBS = result[result.length - 2];
          const PBS = result[result.length - 1];
          resultArray.push({
            name,
            SIR,
            PIR,
            CBS,
            PBS,
          });
        });
        resolve(resultArray);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 设置oltacsvlan
  async setOltAcsVlan(acsVlan, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        acsVlan,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_OLTACSVLAN',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取onuList列表
  async getOnuList(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'ONU_LIST',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const arr = [];
        if(msg.indexOf('No related information to show') != -1){
          return resolve(arr)
        }
        const lines = msg
            .replace(/\u0008/g, '')
            .replace(/\s*--More--\s*/g, '\n')
            .split('\n');
        let titleArray =[
          'OnuIndex',
          'Admin State',
          'OMCC State',
          'O7 State',
          'Phase State',
          'Channel'
        ];
        const colInfo = [];
        const title = lines.filter(
          value => value.indexOf(titleArray[0]) != -1
        );
        if(!title.length){
          return resolve(arr);
        }
        titleArray = titleArray.filter(
          value=>title[0].indexOf(value)!==-1
        )
        titleArray.forEach(titleItem =>
          colInfo.push(title[0].indexOf(titleItem))
        );
        let phaseStateIndex = titleArray.findIndex(item=>/phase state/i.test(item));
        const contents = lines.filter(
          value =>
            value.indexOf('---') == -1 &&
            value.indexOf('ONU Number') == -1 &&
            value.indexOf('show') == -1 &&
            value.indexOf('kbps') == -1 &&
            value.indexOf('Command') == -1 &&
            value.indexOf('Note') == -1 &&
            value.indexOf(this.options.systemName) == -1 &&
            value.indexOf('display') == -1 &&
            value.indexOf('Total') == -1 &&
            value.indexOf('config') == -1 &&
            value.indexOf(titleArray[0]) == -1 &&
            value.indexOf('>') == -1
        );
        contents.forEach(item => {
          const obj = new Object();
          obj[titleArray[0]] = item.substring(colInfo[0], colInfo[1]).trim();
          let state ='N/A';
          if(phaseStateIndex!==-1){
            state = item.substring(colInfo[phaseStateIndex], colInfo[phaseStateIndex+1]).trim();
          }
          if (obj[titleArray[0]].indexOf('gpon-onu_') == -1) {
            obj[titleArray[0]] = 'gpon-onu_' + obj[titleArray[0]];
          }
          arr[obj[titleArray[0]]] = {
            port:obj[titleArray[0]],
            state
          }
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  parseDetail(item){
    const onlyindex = item
    .substring(
      item.indexOf('ONU interface:') + 14,
      item.indexOf('Name')
    )
    .replace(/\r\0/, '')
    .trim();
    const name = item.substring(item.indexOf('Name:') + 5, item.indexOf('Type')).replace(/\r\0/, '').trim();
    const type = item.substring(item.indexOf('Type:') + 5, item.indexOf('State')).replace(/\r\0/, '').trim();
    const status = item
      .substring(
        item.indexOf('Phase state:') + 13,
        item.indexOf('Config state') == -1
          ? item.indexOf('Authentication mode')
          : item.indexOf('Config state')
      )
      .replace(/\r\0/, '')
      .trim(); // OffLine Working
    const sn = item
      .substring(
        item.indexOf('Serial number:') + 14,
        item.indexOf('Password')
      )
      .replace(/\r\0/, '')
      .trim();
      return  {
      ONUname: name,
      PONindex: onlyindex.split(':')[0],
      ONUindex: onlyindex.split(':')[1],
      onlyindex,
      sn,
      status,
      number: onlyindex.split(':')[1],
      slot: onlyindex.split(':')[0].split('/')[1],
      port: onlyindex.split(':')[0].split('/')[2],
      onuType:type
    } 
  }
  parseRx(rxStr){
    // 处理rx
    try {
      if(rxStr.indexOf('Rx power') !== -1){
        let titleArray = [ 'Onu', 'Rx power' ];
        let lines = rxStr.split('\n');
        let title = lines.filter(value => value.indexOf(titleArray[0]) != -1);
        const colInfo = [];
        titleArray.forEach(titleItem => {
            colInfo.push(title[0].indexOf(titleItem));
        });
        const contents = lines.filter(
            value =>
            value.indexOf('---') == -1 &&
            value.indexOf('onu-rx') == -1 &&
            value.indexOf('#') == -1
        );
        let Rx = contents[1].substring(colInfo[1]);
        return {Rx};
      }else{
        return null;
      }
    } catch (error) {
      console.log(error)
      return null;
    }
  }
  // 获取onuListMsg --- 废弃
  async getOnuListMsg1(onuArr, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        onuArr,
      };
      try {
        const resultArray = [];
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_DETAIL_INFO',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        for(let i=0;i<resultArr.length;i+=2){
          let detailStr = resultArr[i];
          let rxStr = resultArr[i+1];
          let {ONUname,PONindex, ONUindex, onlyindex, sn, status, number, slot, port, onuType} = this.parseDetail(detailStr)
          let {Rx} = this.parseRx(rxStr);
          resultArray.push({
            ONUname,
            PONindex,
            ONUindex,
            onlyindex,
            sn,
            status,
            number,
            slot,
            port,
            onuType,
            Rx
          });
        }
        resolve(resultArray);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取onuFindList
  async getUnregisteredONUList(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'ONU_FIND',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const arr = [];
        if (msg.indexOf('%Code') != -1) {
          return resolve(arr);
        }
        const lines = msg.split('\n');
        const titleArray = [ 'OnuIndex', 'Sn', 'State' ];
        const colInfo = [];
        const title = lines.filter(
          value => value.indexOf(titleArray[0]) != -1
        );
        titleArray.forEach(titleItem => {
          colInfo.push(title[0].indexOf(titleItem));
        });
        const contents = lines.filter(
          value =>
            value.indexOf('---') == -1 &&
            value.indexOf('ONU Number') == -1 &&
            value.indexOf('show') == -1 &&
            value.indexOf('kbps') == -1 &&
            value.indexOf('Command') == -1 &&
            value.indexOf('Note') == -1 &&
            value.indexOf(this.options.systemName) == -1 &&
            value.indexOf('display') == -1 &&
            value.indexOf('Total') == -1 &&
            value.indexOf('config') == -1 &&
            value.indexOf(titleArray[0]) == -1 &&
            value.indexOf('>') == -1
        );
        contents.forEach(item => {
          const obj = new Object();
          obj[titleArray[0]] = item.substring(colInfo[0], colInfo[1]).trim();
          obj[titleArray[1]] = item.substring(colInfo[1], colInfo[2]).trim();
          obj[titleArray[2]] = item.substring(colInfo[2], colInfo[3]).trim();
          arr.push({
            PONindex: obj[titleArray[0]].split(':')[0],
            slot: obj[titleArray[0]].split(':')[0].split('/')[1],
            port: obj[titleArray[0]].split(':')[0].split('/')[2],
            sn: obj[titleArray[1]],
            status: obj[titleArray[2]],
          });
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 设置已注册onu的acs地址
  async setRegisteredOnuAcsUrl(onuList, acsVlan, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        acsVlan,
        onuList,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_REGISTEREDONUACSURL',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 添加card
  async createCard(slot, type, oltHardVersion, me) {
    if (type.indexOf('GTGH') != -1) {
      type = 'GTGH';
    }
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        slot,
        type,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('%Code') != -1) {
            return {
              result: false,
              message: msg
                .substring(msg.indexOf(':') + 1, msg.indexOf(view.prompt))
                .trim(),
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CREATE_CARD',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  // 删除card
  async deleteCard(slot, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        slot,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('%Code') != -1) {
            return {
              result: false,
              message: msg
                .substring(msg.indexOf(':') + 1, msg.indexOf(view.prompt))
                .trim(),
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETE_CARD',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  // 开启所有ponport口
  async openAllPonPorts(arr, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        arr,
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'OPEN_ALL_PONPORTS_STATUS',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 查询ponport的onus、光功率、距离
  async getPonPortMsg(portResult, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        portResult,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_PONPORTMSG',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const result = {
          onus: '',
          range: '',
          Txpwr: '',
          adminStatus: '',
          min: '',
          max: '',
        };
        const msg = resultArr[1];
        const lines = msg
            .replace(/\u0008/g, '')
            .replace(/\s*--More--\s*/g, '\n')
            .split('\n');
        const titleArray = [
          'OltInterface',
          'Base-distance(100m)',
          'Maximum-distance(100m)',
        ];
        const colInfo = [];
        const title = lines.filter(
          value => value.indexOf(titleArray[0]) != -1
        );
        titleArray.forEach(titleItem =>
          colInfo.push(title[0].indexOf(titleItem))
        );
        const contents = lines.filter(
          value =>
            value.indexOf('---') == -1 &&
            value.indexOf('show') == -1 &&
            value.indexOf('kbps') == -1 &&
            value.indexOf('Command') == -1 &&
            value.indexOf('Note') == -1 &&
            value.indexOf(this.options.systemName) == -1 &&
            value.indexOf('display') == -1 &&
            value.indexOf('Total') == -1 &&
            value.indexOf('config') == -1 &&
            value.indexOf(titleArray[0]) == -1 &&
            value.indexOf('>') == -1
        );
        const min = contents[0].substring(colInfo[1], colInfo[2]).trim();
        const max = contents[0].substring(colInfo[2], colInfo[3]).trim();
        if (resultArr[0].indexOf('deactivate') != -1) {
          result.adminStatus = 'down';
        } else if (resultArr[0].indexOf('activate') != -1) {
          result.adminStatus = 'up';
        }
        if(oltHardVersion.indexOf('V1.2.5') != -1){
          result.onus = resultArr[0]
            .substring(
              resultArr[0].indexOf('Registered onu number:') + 22,
              resultArr[0].indexOf('OLT statistic')
            )
            .trim()
            .replace('.', '');
          result.Txpwr = resultArr[2]
            .substring(
              resultArr[2].indexOf('Tx power:') + 9,
              resultArr[2].indexOf(view.prompt)
            )
            .trim();
        }else if(oltHardVersion.indexOf('V2.1.0') != -1){
          result.onus = resultArr[0]
          .substring(
            resultArr[0].indexOf('the number of registered onus is') + 32,
            resultArr[0].indexOf('Current channel num')
          )
          .trim()
          .replace('.', '');
          result.Txpwr = resultArr[2].split('\n')[2].replace(/\s{2,}/g,'|').split('|')[1].trim()
        }
        result.range = min + '-' + max;
        result.min = min;
        result.max = max;
        resolve(result);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 设置ponport距离和状态
  async setPonPortMsg(portResult, cmd, min, max, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        portResult,
        cmd,
        min,
        max,
      };
      try {
        const fn = function(msg) {
          console.log('这里是fn,',msg)
          if (msg.indexOf('%Code') != -1) {
            return {
              result: false,
              message: msg
                .substring(msg.indexOf(':') + 1, msg.indexOf(view.prompt))
                .trim(),
            };
          } else if (msg.indexOf('Successful') != -1) {
            return { result: true };
          }
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_PONPORTMSG',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取uplink的tagvlan和untagvlan
  async getUplinkMsg(uplinkResult, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        uplinkResult,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_UPLINKMSG',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const result = {
          tagvlan: '',
          untagvlan: '',
          adminStatus: '',
        };
        result.tagvlan = resultArr[0]
          .substring(
            resultArr[0].indexOf('TaggedVlan:') + 11,
            resultArr[0].indexOf(view.prompt)
          )
          .trim();
        result.untagvlan = resultArr[0]
          .substring(
            resultArr[0].indexOf('UntaggedVlan:') + 13,
            resultArr[0].indexOf('TaggedVlan:')
          )
          .trim();
        if (
          resultArr[1].indexOf(
            `${uplinkResult.port} is administratively down`
          ) != -1
        ) {
          result.adminStatus = 'down';
        } else {
          result.adminStatus = 'up';
        }
        if(result.tagvlan===undefined){
          result.tagvlan='';
        }
        if(result.untagvlan===undefined){
          result.untagvlan='';
        }
        resolve(result);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 修改uplink 状态、tagVlan、unTagVlan
  async setUplinkMsg(
    uplinkResult,
    tagVlan,
    removeTagVlan,
    cmd,
    unTagVlan,
    oltHardVersion,
    me
  ) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        uplinkResult,
        tagVlan,
        removeTagVlan,
        cmd,
        unTagVlan,
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_UPLINKMSG',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 创建vlan
  async setVlan(vlanId, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        vlanId,
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_VLAN',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 删除vlan
  async deleteVlan(vlanId, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        vlanId,
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETE_VLAN',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 创建speedprofile
  async speedProfileCreate(name, PIR, SIR, CBS, PBS, oltHardVersion, me) {
    if (CBS == 'default') {
      CBS = '';
    }
    if (PBS == 'default') {
      PBS = '';
    }
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        name,
        PIR,
        SIR,
        CBS,
        PBS,
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CREATE_SPEEDPROFILE',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 修改speedprofile
  async speedProfileEdit(name, PIR, SIR, CBS, PBS, oltHardVersion, me) {
    if (CBS == 'default') {
      CBS = '';
    }
    if (PBS == 'default') {
      PBS = '';
    }
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        name,
        PIR,
        SIR,
        CBS,
        PBS,
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'EDIT_SPEEDPROFILE',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 删除speedprofile
  async speedProfileDelete(name, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        name,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('%Code') != -1) {
            let row = msg.split('\r\n').find(item=>item.indexOf('%Code') != -1)
            return {
              result: false,
              message: row.trim(),
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETE_SPEEDPROFILE',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  // 创建onutype
  async onuProfileCreate(eth, pots, rf, name, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        eth,
        pots,
        rf,
        name,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('%Code') != -1) {
            return {
              result: false,
              message: msg
                .substring(msg.indexOf(':') + 1, msg.indexOf(view.prompt))
                .trim(),
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CREATE_ONUPROFILE',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  // 获取onutype
  async getOnuProfileMsg(onuProfileResult, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        onuProfileResult,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_ONUPROFILEMSG',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const result = {
          eth: 0,
          pots: 0,
          catv: 0,
        };
        const msg = resultArr[0].split('\n');
        for (let i = 0; i < msg.length; i++) {
          if (msg[i].indexOf('eth_0/') != -1) {
            result.eth++;
          }
          if (msg[i].indexOf('pots_0/') != -1) {
            result.pots++;
          }
          if (msg[i].indexOf('rf_0/') != -1) {
            result.catv++;
          }
        }
        resolve(result);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 修改onutype
  async onuProfileEdit(onuProfileResult, eth, pots, rf, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        onuProfileResult,
        eth,
        pots,
        rf,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('40296') != -1) {
            return {
              result: false,
              message: msg
                .substring(msg.indexOf(':') + 1, msg.indexOf(view.prompt))
                .trim(),
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'EDIT_ONUPROFILE',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  // 删除onutype
  async onuProfileDelete(onuProfileResult, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        onuProfileResult,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('%Code') != -1) {
            return {
              result: false,
              message: msg.split('\r\n').find(item=>item.indexOf('%Code') != -1),
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETE_ONUPROFILE',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  // 创建dbaProfile
  async dbaProfileCreate(name, type, max, fbw, abw, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        name,
        type,
        max,
        fbw,
        abw
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('%Code') != -1) {
            return {
              result: false,
              message: msg
                .substring(msg.indexOf(':') + 1, msg.indexOf(view.prompt))
                .trim(),
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CREATE_DBAPROFILE',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  // 修改dbaprofile
  async dbaProfileEdit(name, type, max,fbw,abw,oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        name,
        type,
        max,
        fbw,
        abw
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('%Code') != -1) {
            let errLine = msg.split('\n').filter(item=>item.indexOf('%Code') !== -1)
            return {
              result: false,
              message:errLine,
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'EDIT_DBAPROFILE',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  // 删除dbaProfile
  async dbaProfileDelete(name, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        name,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('%Code') != -1) {
            return {
              result: false,
              message: msg.split('\r\n').find(item=>item.indexOf('%Code') != -1),
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETE_DBAPROFILE',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  //---------------------------------------------------------------------------------------------
  async DeleteCommunity_ZTE(CommunityArr, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        CommunityArr,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETE_COMMUNITY',
            oltHardVersion: 'NONE',
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        resolve(false);
      }
    });
  }
  async SetCommunity_ZTE(rocommunity, rwcommunity, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;

      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        rwcommunity,
        rocommunity,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'MODIFY_COMMUNITY',
            oltHardVersion: 'NONE',
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        resolve(false);
      }
    });
  }
  async GetCommunity_ZTE(me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;

      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_COMMUNITY',
            oltHardVersion: 'NONE',
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const reg = /snmp-server community(\s\w*\W*\s)/g;
        const arr = msg.match(reg);
        if (arr == null) {
          resolve(null);
        } else {
          const result = [];
          arr.forEach(item => {
            result.push(item.replace('snmp-server community', '').trim());
          });
          resolve(result);
        }
      } catch (error) {
        resolve(null);
      }
    });
  }
  async getonufind_ZTE(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'ONU_FIND',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const onuUncfgArr = msg.split('\n');
        onuUncfgArr.pop();
        const resultArray = [];
        onuUncfgArr.forEach(item => {
          if (item.indexOf('gpon-onu') != -1) {
            const result = item
              .trim()
              .replace(/\s{2,}/g, '|')
              .split('|');
            const PONindex = result[0].split(':')[0];
            const ONUindex = result[0].split(':')[1];
            const SN = result[1];
            const state = result[2];
            resultArray.push({
              PONindex,
              ONUindex,
              SN,
              state,
            });
          }
        });
        resolve(resultArray);
      } catch (error) {
        reject(error);
      }
    });
  }
  async getDbaProfile_ZTE(oltHardVersion, me) {
    // 中兴需要获取tcountprofile,供onu使用
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DBA_PROFILE',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const resultArray = [];
        const strArr = msg.toLowerCase().split('name');
        strArr.shift();
        strArr.forEach(item => {
          const arr = item.split('\n');
          const name = arr[0].split(':')[1].trim();
          const params = arr[2].trim().replace(/\s+/g, '|').split('|');
          const type = params[0].trim();
          const FBW = params[1].trim();
          const ABW = params[2].trim();
          const MBW = params[3].trim();
          const PRIORITY =
            typeof params[4] === 'undefined'
              ? 'N/A'
              : params[4].trim().toUpperCase();
          const WEIGHT =
            typeof params[5] === 'undefined'
              ? 'N/A'
              : params[5].trim().toUpperCase();
          resultArray.push({
            name,
            type,
            FBW,
            ABW,
            MBW,
            PRIORITY,
            WEIGHT,
          });
        });
        resolve(resultArray);
      } catch (error) {
        reject(error);
      }
    });
  }
  async getVlanTable(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_VLAN',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const arr = [];
        const infoArr = msg.split(':');
        const vlanStrArr = infoArr[2].replace(/\n/g, '').match(/(\d*-?\d+,?)/g);
        vlanStrArr.forEach(item => {
          arr.push({
            VlanID: item.replace(',', ''),
            Memo: item.replace(',', ''),
            vlanTagPort: '',
            vlanUntagPort: '',
            vlanRowStatus: '',
          });
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  async getPonPortList(ctx) {
    return new Promise(async (resolve, reject) => {
      const arr = [];
      const session = await createSession.call({ctx,
        proxyFlag : this.options.proxyFlag},this.options.ip,this.options.community,this.options);
      session.table('1.3.6.1.2.1.2.2', function(error, table) {
        if (error) {
          return reject(error);
        }
        for (const key in table) {
          if (table[key][2].indexOf('gpon') != -1) {
            // 2认为是pon port
            const ifIndex = table[key][2].toString().split('/')[2];
            arr.push({
              ifIndex,
              slot: table[key][2].toString().split('/')[1],
              port: table[key][2].toString(),
              type: table[key][2].toString().split('_')[0],
              status: table[key][7].toString(),
            });
          }
        }
        arr.sort((a, b) => a.ifIndex - b.ifIndex);
        resolve(arr);
        session.close();
      });
    });
  }
  static isNumber(str) {
    const n = Number(str);
    if (!isNaN(n)) {
      return true;
    }
    return false;
  }
  async getOltTx_ZTE(ponPortsArray, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ponPortsArray,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_PON_TX',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const reg1 = /GPON\)+(.*)\n/;
        const reg2 = /Tx power:(.*)\n/;
        const TxArr = [];
        resultArr.forEach((item, index) => {
          const groups1 = reg1.exec(item);
          if (groups1 != null && groups1.length > 1) {
            TxArr.push({
              index,
              tx: groups1[1].trim().replace('(dbm)', ''),
            });
          }
          const groups2 = reg2.exec(item);
          if (groups2 != null && groups2.length > 1) {
            TxArr.push({
              index,
              tx: groups2[1].trim().replace('(dbm)', ''),
            });
          }
        });
        resolve(TxArr);
      } catch (error) {
        reject(error);
      }
    });
  }
  async getPonTx(ponPortsArray, oltHardVersion, me) {
    try {
      me.proxyFlag = this.options.proxyFlag;
      const arr = await this.getOltTx_ZTE(ponPortsArray, oltHardVersion, me);
      ponPortsArray.forEach((item, index) => {
        item.TXPower = ZTEOLT.isNumber(arr[index].tx) ? arr[index].tx : 'N/A';
      });
      return ponPortsArray;
    } catch (error) {
      return error;
    }
  }
  async getCard_ZTE(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CARD_LIST',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        // 获取title
        const msg = resultArr[0];
        const lines = msg.split('\n');
        const titleArray = [
          'Rack',
          'Shelf',
          'Slot',
          'CfgType',
          'RealType',
          'Port',
          'HardVer',
          'SoftVer',
          'Status',
        ];
        const colInfo = [];
        const title = lines.filter(
          value => value.indexOf(titleArray[0]) != -1
        );
        titleArray.forEach(titleItem => {
          colInfo.push(title[0].indexOf(titleItem));
        });
        const contents = lines.filter(value => {
          const result =
            value.indexOf('---') == -1 &&
            value.indexOf('show card') == -1 &&
            value.indexOf(titleArray[0]) == -1 &&
            value.indexOf('config') == -1;
          return result;
        });
        const arr = [];
        contents.forEach(item => {
          const obj = new Object();
          obj[titleArray[0]] = item.substring(colInfo[0], colInfo[1]);
          obj[titleArray[1]] = item.substring(colInfo[1], colInfo[2]);
          obj[titleArray[2]] = item.substring(colInfo[2], colInfo[3]);
          obj[titleArray[3]] = item.substring(colInfo[3], colInfo[4]);
          obj[titleArray[4]] = item.substring(colInfo[4], colInfo[5]);
          obj[titleArray[5]] = item.substring(colInfo[5], colInfo[6]);
          obj[titleArray[6]] = item.substring(colInfo[6], colInfo[7]);
          obj[titleArray[7]] = item.substring(colInfo[7], colInfo[8]);
          obj[titleArray[8]] = item.substr(colInfo[8]);
          arr.push({
            slot: obj[titleArray[2]].trim(),
            cardType: obj[titleArray[3]].trim(),
            realType: obj[titleArray[4]].trim(),
            numberOfPorts: obj[titleArray[5]].trim(),
            softwateVersion: obj[titleArray[7]].trim(),
            cardStatus:
              obj[titleArray[8]].trim() == 'HWONLINE'
                ? 'Auto_find'
                : obj[titleArray[8]].trim(),
          });
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  async getUplinkPortInfo(ctx) {
    const maxRepetitions = 20;
    const oid1 = '1.3.6.1.2.1.31.1.1';
    const columns1 = [ 1 ];
    const oid2 = '1.3.6.1.2.1.2.2';
    const columns2 = [ 7 ];
    const p1 = new Promise(async (resolve, reject) => {
      const session = await createSession.call({ctx,
        proxyFlag : this.options.proxyFlag},this.options.ip,this.options.community,this.options);
      session.tableColumns(
        oid1,
        columns1,
        maxRepetitions,
        function(error, table) {
          if (error) {
            return reject(error);
          }
          return resolve(table);
        }
      );
    });
    const p2 = new Promise(async (resolve, reject) => {
      const session = await createSession.call({ctx,
        proxyFlag : this.options.proxyFlag},this.options.ip,this.options.community,this.options);
      session.tableColumns(
        oid2,
        columns2,
        maxRepetitions,
        function(error, table) {
          if (error) {
            return reject(error);
          }
          return resolve(table);
        }
      );
    });
    return Promise.all([ p1, p2 ]);
  }
  async getUplinkSpeedAndVlan(list, oltHardVersion, me) {
    const arr = [];
    for (const item in list) {
      arr.push(item);
    }
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        list,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_UPLINK_SPEED_AND_VLAN',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resultArr.shift();
        const resultArray = [];
        let temp = Object.create(null);
        resultArr.forEach((item, index) => {
          const a = Math.floor(index / 2);
          switch (index % 2) {
            case 0:
              // speed
              const msg = item.replace(/-{5,}/g, '|').split('|')[2];
              temp.Speed = msg.replace(/\s{1,}/g, '|').split('|')[6];
              const linkStatus = msg.replace(/\s{1,}/g, '|').split('|')[10];
              if (linkStatus == 'down') {
                temp.LinkStatus = 2;
              } else if (linkStatus == 'up') {
                temp.LinkStatus = 1;
              }
              break;
            case 1:
              // vlan
              const UnTagvlan = item
                .substring(
                  item.indexOf('UntaggedVlan:') + 13,
                  item.indexOf('TaggedVlan')
                )
                .trim();
              if (UnTagvlan == '1') {
                temp.UnTagvlan = '';
              } else {
                temp.UnTagvlan = UnTagvlan;
              }
              temp.Tagvlan = item
                .substring(
                  item.indexOf('TaggedVlan:') + 11,
                  item.indexOf(`${this.options.systemName}`)
                )
                .trim();
              break;
          }
          if (index % 2 == 1) {
            temp.PortID = list[arr[a]].PortID;
            temp.AdminStatus = list[arr[a]].AdminStatus;
            resultArray.push(temp);
            temp = Object.create(null);
          }
        });
        resolve(resultArray);
      } catch (error) {
        reject(error);
      }
    });
  }
  async getmacTable_ZTE(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;

      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'MAC_LIST',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        let msg = resultArr[0];
        const arr = [];
        if (msg.indexOf('Total mac address : 0') == -1) {
          msg = msg
            .replace(/\u0008/g, '')
            .replace(/\s*--More--\s*/g, '\n')
            .replace(/-+/, '|');
          const msgArr = msg.split('|')[1].trim().split('\n');
          msgArr.pop();
          msgArr.forEach(item => {
            item = item.replace(/\s+/g, '|');
            const params = item.split('|');
            arr.push({
              VlanID: params[1].toString(),
              Mac: params[0].toString().replace(/\./g, '-'),
              Type: params[2].toString(),
              PhysicalPort: params[3].toString(),
            });
          });
          resolve(arr);
        } else {
          resolve(null);
        }
      } catch (error) {
        resolve(error);
      }
    });
  }
  async setVlans_ZTE(vlanID, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        vlanID,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_VLAN',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  async deleteVlan_ZTE(vlanID, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;

      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        vlanID,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETE_VLAN',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        if (msg.indexOf('30519') != -1 || msg.indexOf('30514') != -1) {
          reject(msg);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  async setONU(
    ONUindex,
    PONindex,
    PONOLTName,
    ONUProfileName,
    name,
    sn,
    oltHardVersion,
    acsVlan,
    lineProfileName,
    remoteProfileName,
    remoteProfileBusiness,
    me
  ) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.prompt,
        ManagementPassword: this.options.managementPassword,
        ONUindex,
        PONindex,
        PONOLTName,
        ONUProfileName,
        name,
        sn,
        acsVlan,
        lineProfileName,
        remoteProfileName,
        arr: remoteProfileBusiness,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('The entry is existed') != -1) {
            return { result: false, message: 'The entry is existed' };
          } else if (msg.indexOf('Profile does not exist') != -1) {
            return {
              result: false,
              message: 'DBA profile or Uplink/Down speed does not exist',
            };
          } else if (msg.indexOf('Not support this ONU') != -1) {
            return { result: false, message: 'Onu profile does not exist' };
          } else if (msg.indexOf('GPON ONU sn already exists') != -1) {
            return { result: false, message: 'GPON ONU sn already exists' };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CREATE_ONUFIND',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length !== 0) {
          resolve(resultArr);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  async deleteONU(PONOLTName, ONUindex, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        PONOLTName,
        ONUindex,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETE_ONU',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }

  async saveOlt(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SAVE',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  async rebootOlt(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'REBOOT',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  async setVlanMemo(VlanID, Memo, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        VlanID,
        Memo,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_VLAN_MEMO',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  async getVlanDesc(list, oltHardVersion, me) {
    const arr = [];
    for (let i = 0; i < list.length; i++) {
      if (list[i].VlanID.indexOf('-') != -1) {
        for (
          let j = list[i].VlanID.split('-')[0];
          j <= list[i].VlanID.split('-')[1];
          j++
        ) {
          arr.push({ VlanID: '' + j });
        }
      } else {
        arr.push({ VlanID: list[i].VlanID });
      }
    }
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        arr,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_VLAN_DESC',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resultArr.shift();
        resultArr.forEach((item, index) => {
          arr[index].Memo = item
            .substring(
              item.indexOf('description') + 11,
              item.indexOf('multicast-packet')
            )
            .replace(':', '')
            .trim();
          const untaglist = item
            .substring(
              item.indexOf('port(untagged):') + 15,
              item.indexOf('port(tagged)')
            )
            .trim()
            .split('\n');
          const taglist = item
            .substring(
              item.indexOf('port(tagged):') + 13,
              item.indexOf(this.options.systemName)
            )
            .trim()
            .split('\n');
          const uplinklist = {};
          uplinklist.untagArr = getArr(untaglist);
          uplinklist.tagArr = getArr(taglist);
          arr[index].uplinklist = JSON.stringify(uplinklist);
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  async binduplink(untag, bindlist, unbindlist, VlanID, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        untag,
        bindlist,
        unbindlist,
        VlanID,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_VLAN_DESC',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resultArr.shift();
        resultArr.forEach((item, index) => {
          arr[index].Memo = item
            .substring(
              item.indexOf('description') + 11,
              item.indexOf('multicast-packet')
            )
            .replace(':', '')
            .trim();
          const untaglist = item
            .substring(
              item.indexOf('port(untagged):') + 15,
              item.indexOf('port(tagged)')
            )
            .trim()
            .split('\n');
          const taglist = item
            .substring(
              item.indexOf('port(tagged):') + 13,
              item.indexOf(this.options.systemName)
            )
            .trim()
            .split('\n');
          const uplinklist = {};
          uplinklist.untagArr = getArr(untaglist);
          uplinklist.tagArr = getArr(taglist);
          arr[index].uplinklist = JSON.stringify(uplinklist);
        });
        resolve(arr);
      } catch (error) {
        reject(error);
      }
    });
  }
  async getUplinkAdminStatusAndVlan(uplinkport, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        uplinkport,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_UPLINK_ADMINSTATUS_AND_VLAN',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resultArr.shift();
        const temp = Object.create(null);
        resultArr.forEach((item, index) => {
          switch (index % 2) {
            case 0:
              // AdminStatus
              const msg = item.replace(/-{5,}/g, '|').split('|')[2];
              const state = msg.replace(/\s{1,}/g, '|').split('|')[9];
              if (state == 'activate') {
                temp.AdminStatus = 1;
              } else if (state == 'deactivate') {
                temp.AdminStatus = 2;
              }
              break;
            case 1:
              // vlan
              const UnTagvlan = item
                .substring(
                  item.indexOf('UntaggedVlan:') + 13,
                  item.indexOf('TaggedVlan')
                )
                .trim();
              if (UnTagvlan == '1') {
                temp.UnTagvlan = '';
              } else {
                temp.UnTagvlan = UnTagvlan;
              }
              temp.Tagvlan = item
                .substring(
                  item.indexOf('TaggedVlan:') + 11,
                  item.indexOf(`${this.options.systemName}`)
                )
                .trim();
              break;
          }
        });
        resolve(temp);
      } catch (error) {
        reject(error);
      }
    });
  }
  async setUplink(
    portID,
    adminStatus,
    addvlan,
    UnTagvlan,
    oldUnTagvlan,
    removevlan,
    oltHardVersion,
    me
  ) {
    if (adminStatus == 1) {
      var type = 'no shutdown';
    } else if (adminStatus == 2) {
      var type = 'shutdown';
    }
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        portID,
        type,
        addvlan,
        UnTagvlan,
        oldUnTagvlan,
        removevlan,
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_UPLINK',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }

  async oltBackUp(id, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      const result = {
        msg: '',
        flag: false,
      };
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        host: me.app.config.ftpIP,
        ftpName: me.app.config.ftpUsername,
        ftpPassword: me.app.config.ftpPassword,
        fileName: 'startrun.dat',
        id,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'BACKUP',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        result.msg = 'backup successful';
        result.flag = true;
        resolve(result);
      } catch (error) {
        console.log('===备份文件报错了===')
        console.log(error)
        console.log('===备份文件报错了===')
        result.msg = 'backup fail,' + error;
        result.flag = false;
        resolve(result);
      }
    });
  }
  async oltRestore(id, oltHardVersion, fileName, me) {
    const result = {
      flag: false,
      data: '',
    };
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        host: me.app.config.ftpIP,
        ftpName: me.app.config.ftpUsername,
        ftpPassword: me.app.config.ftpPassword,
        fileName,
        id,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('%Code') != -1) {
            return {
              result: false,
              message: msg
                .substring(
                  message.indexOf(':') + 1,
                  msg.indexOf(this.options.systemName)
                )
                .trim(),
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'RESTORE',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length != 0) {
          result.flag = false;
          result.data = 'upload fail,' + resultArr[0];
          resolve(result);
        } else {
          result.flag = true;
          result.data = 'upload successful';
          resolve(result);
        }
      } catch (error) {
        result.flag = false;
        result.data = 'upload fail,' + error;
        resolve(result);
      }
    });
  }
  async oltInit(oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'OLT_INIT',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  async getOnuBindInfo(oltHardVersion, ponIndex, onuIndex, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ponIndex,
        onuIndex,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_TCONT_VPORT_SRVPORT',
            oltHardVersion: 'NONE',
            view,
          },
          null,
          me
        );
        const msg = resultArr[0];
        const getInfoFromStr = function(str, type) {
          try {
            const s = str.substring(str.indexOf(type), str.length);
            const t = s.replace(/\s{1,}/g, '|').split('|')[1];
            return t;
          } catch (error) {
            console.log(error);
            return null;
          }
        };
        const arr = msg.split('\n');

        const tcount = [],
          gemport = [],
          vport = [],
          srvport = [];
        arr.forEach(item => {
          if (item.indexOf('tcont') !== -1) {
            const t = getInfoFromStr(item, 'tcont');
            if (tcount.length === 0) {
              tcount.push(t);
            } else if (t && parseInt(t) > parseInt(tcount[tcount.length - 1])) {
              tcount.push(t);
            }
          }
          if (item.indexOf('gemport') !== -1) {
            const g = getInfoFromStr(item, 'gemport');
            if (gemport.length === 0) {
              gemport.push(g);
            } else if (
              g &&
              parseInt(g) > parseInt(gemport[gemport.length - 1])
            ) {
              gemport.push(g);
            }
          }
          if (item.indexOf('vport') !== -1) {
            const g = getInfoFromStr(item, 'vport');
            if (vport.length === 0) {
              vport.push(g);
            } else if (g && parseInt(g) > parseInt(vport[vport.length - 1])) {
              vport.push(g);
            }
          }
          if (item.indexOf('service-port') !== -1) {
            const g = getInfoFromStr(item, 'service-port');
            if (srvport.length === 0) {
              srvport.push(g);
            } else if (
              g &&
              parseInt(g) > parseInt(srvport[srvport.length - 1])
            ) {
              srvport.push(g);
            }
          }
        });
        const result = {
          tcontMax: parseInt(tcount[tcount.length - 1]) + 1,
          gemportMax: parseInt(gemport[gemport.length - 1]) + 1,
          vportMax: parseInt(vport[vport.length - 1]) + 1,
          srvportMax: parseInt(srvport[srvport.length - 1]) + 1,
        };
        resolve(result);
      } catch (error) {
        reject(error);
      }
    });
  }
  /**
   * 给onu绑定其他vlan
   * @param {*} oltHardVersion
   * @param {*} ponIndex
   * @param {*} onuIndex
   * @param {*} vlan
   * @param {*} me
   * @return
   */
  async onuBindVlan(
    oltHardVersion,
    ponIndex,
    onuIndex,
    vlan,
    tcont,
    dba,
    gemport,
    vport,
    srvport,
    upstream,
    downstream,
    me
  ) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const date = new Date().getTime();
      // 组装模板变量
      const view = {
        username: this.options.username,
        password: this.options.password,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ponIndex,
        onuIndex,
        vlan,
        tcont,
        dba,
        gemport,
        vport,
        srvport,
        serviceName: date.toString(),
        upstream,
        downstream,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_ONU_VLAN',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  // 创建lineprofile
  async lineProfileCreate(oltHardVersion, name, bussinessArr, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        lineProfileName: name,
        arr: bussinessArr,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CREATE_LINEPROFILE',
            oltHardVersion: oltHardVersion || 'NONE',
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    });
  }
  async lineProfileDelete(oltHardVersion, name, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        lineProfileName:name,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('%Code') != -1) {
            let message = msg.split('\r\n').find(item=>item.indexOf('%Code')!=-1)
            return {
              result: false,
              message
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETE_LINEPROFILE',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if (resultArr.length !== 0) {
          reject(resultArr[0]);
        } else {
          resolve(true);
        }
      } catch (error) {
        reject(error);
      }
    });
  }
  async changeOnuName(data,me,version){
   console.log(data)
    return new Promise(async(resolve,reject)=>{
      const addr = this.options.ip +':'+this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        data,
      }
      let fn = res=>{
        console.log(res)
      }
      try{
        await common.run_EX(
          addr, {
            oltType: 'ZTE',
            mountPoint: 'CHANGE_ONUNAME',
            oltHardVersion: version,                         
            view,
          },
          fn,
          me
        );
     
       resolve('success');
      
      } catch(error){
        reject(error);
      }
    })
}
  async lineProfileNameCheck(oltHardVersion, name, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        name,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('Invalid') !== -1) {
            return {
              result: false,
              message: msg
                .substring(
                  msg.indexOf('Invalid:') + 8,
                  msg.indexOf(view.prompt)
                )
                .trim(),
            };
          }
          return { result: true };
        };
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_LINEPROFILELIST',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        if(resultArr.find(item=>item.indexOf('Code 70285 : No related information to show')!==-1)){
          return resolve([])
        }
        const profileArr =
          resultArr &&
          resultArr.filter(
            item => item.indexOf('Profile name') !== -1||item.indexOf('ProfileName')!==-1
          );
        let nameArr = [];
        profileArr.forEach(item=>{
          let temp = getNames(item)
          nameArr = nameArr.concat(temp)
        })
        resolve(nameArr.filter(item => item.length > 0));
      } catch (error) {
        reject(error);
      }
    });
  }
  async getONUDetails(onuAddress, oltHardVersion, me) {
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        onuAddress,
      };
      try {
        const fn = function(msg) {
          if (msg.indexOf('Invalid') !== -1) {
            return {
              result: false,
              message: msg
                .substring(
                  msg.indexOf('Invalid:') + 8,
                  msg.indexOf(view.prompt)
                )
                .trim(),
            };
          }
          return { result: true };
        };
        const dest = {};
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_ONU_DETAILS',
            oltHardVersion,
            view,
          },
          fn,
          me
        );
        const detailStr =
          (resultArr &&
          resultArr.find(item => item.indexOf('detail-info') !== -1))||(resultArr&&resultArr[0]);
        const txStr =
          (resultArr && resultArr.find(item => item.indexOf('onu-tx') !== -1))||(resultArr&&resultArr[2]);
        // 处理tx
        let titleArray = [ 'Onu', 'Tx power' ];
        let lines = txStr.split('\n');
        let title = lines.filter(value => value.indexOf(titleArray[0]) != -1);
        const colInfo = [];
        titleArray.forEach(titleItem => {
          colInfo.push(title[0].indexOf(titleItem));
        });
        const contents = lines.filter(
          value =>
            value.indexOf('---') == -1 &&
            value.indexOf('onu-tx') == -1 &&
            value.indexOf('#') == -1
        );
        // 处理rx
        const rxStr =
          (resultArr && resultArr.find(item => item.indexOf('onu-rx') !== -1))||(resultArr&&resultArr[1]);
        titleArray = [ 'Onu', 'Rx power' ];
        lines = rxStr.split('\n');
        title = lines.filter(value => value.indexOf(titleArray[0]) != -1);
        const colInfo1 = [];
        titleArray.forEach(titleItem => {
          colInfo1.push(title[0].indexOf(titleItem));
        });
        const contents1 = lines.filter(
          value =>
            value.indexOf('---') == -1 &&
            value.indexOf('onu-rx') == -1 &&
            value.indexOf('#') == -1
        );
        console.log(contents, contents1);
        dest.Tx = contents[1].substr(colInfo[1]);
        dest.Rx = contents1[1].substr(colInfo[1]);
        // 处理onu的大多数信息
        const arr = detailStr
          .replace(/(-{2,})More(-{2,})\u0008{1,}\u0020{1,}/g, '')
          .split(/\r?\u0000?\n/);
          if(arr.length>=3){
            arr.shift();
            arr.pop();
          }
        console.log(arr);
        const keys = [
          'ONU interface',
          'Name',
          'Type',
          'Phase state',
          'Serial number',
        ];

        arr.map(element => {
          console.log(element.trim());
          keys.forEach(key => {
            if (element.trim() && element.trim().startsWith(key)) {
              const t = element.trim().split(':')[1];
              dest[key] = t && t.trim();
            }
          });
        });
        // 处理vlan"show service-port interface gpon-onu_1/2/6:2\nInterface gpon-onu_1/2/6:2\nSport Vport BeginVid EndVid OuterVid InnerVid UserPrio Dscp Etype  Filter Vlan C\nos SVlan SCos Tls  TlsSVid  Mode Ingress Egress  Queue Status Enable\n--------------------------------------------------------------------------------\n--------------------------------------------------------------------\n1     1     112      112    --       --       --       --   --     --     112  -\n-  --    --   --   --       1:1  --      --      --    OK     YES \n2     2     113      113    --       --       --       --   --     --     113  -\n-  --    --   --   --       1:1  --      --      --    OK     YES \n3     3     1030     1030   --       --       --       --   --     --     1030 -\n-  --    --   --   --       1:1  --      --      --    OK     YES \nSport total number:\n3\nZXAN(config)#"
        const vlanStr =
          (resultArr &&
          resultArr.find(item => item.indexOf('show service-port') !== -1))||(resultArr&&resultArr[3]);
        const liness = vlanStr.split('\n');
        const lines_ = liness.filter(
          item => !item.startsWith('-') && item.indexOf('Enable') === -1
        );
        titleArray = [ 'Vlan' ];
        title = lines_.filter(value => value.indexOf(titleArray[0]) != -1);
        const colInfo2 = [];
        titleArray.forEach(titleItem => {
          title[0]&&colInfo2.push(title[0].indexOf(titleItem));
        });
        const contents2 = lines_.filter(
          value =>
            value.indexOf('show') == -1 &&
            value.indexOf('Vlan') == -1 &&
            value.indexOf('#') == -1 &&
            value.indexOf('Interface') == -1 &&
            value.indexOf('total') == -1
        );
        dest.vlan = [];
        contents2.map(item => {
          if (item.length > 4) {
            const str = item.substr(colInfo2[0]);
            const r = /\d{1,}/g;
            const result = str.match(r);
            if(result){
              dest.vlan.push(result[0]);
            }
          }
        });
        resolve(dest);
      } catch (error) {
        reject(error);
      }
    });
  }
  //onu重启
  async reboot(ponIndex, onuIndex, oltHardVersion,me){
    return new Promise(async(resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag;
      const result = {
        msg: '',
        flag: false,
      };
      const addr = this.options.ip+":"+this.options.tPort;
      const cmd = 'reboot';
      const view ={
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ponIndex,
        onuIndex,
        cmd
      }
      try {
        const fn = function(msg) {
          if (msg.indexOf('Invalid') !== -1) {
            return {
              result: false,
              message: msg
                .substring(
                  msg.indexOf('Invalid:') + 8,
                  msg.indexOf(view.prompt)
                )
                .trim(),
            };
          }
          return { result: true };
        };
        const dest = {};
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'ONU_REBOOT',
            oltHardVersion,
            view,
          },
          fn,
          me
        );      
        result.msg = 'reboot successful';
        result.flag = true;
        resolve(result);  
      } catch (error) {
        reject(error)
      }
    })
  }
  //onu disable
  async disable(ponIndex,onuIndex, oltHardVersion,me){
    return new Promise(async(resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag;
      const result = {
        msg: '',
        flag: false,
      };
      const cmd = "shutdown";
      const addr = this.options.ip+":"+this.options.tPort;
      const view ={
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ponIndex,
        onuIndex,
        cmd
      }
      try {
        const fn = function(msg) {
          if (msg.indexOf('Invalid') !== -1) {
            return {
              result: false,
              message: msg
                .substring(
                  msg.indexOf('Invalid:') + 8,
                  msg.indexOf(view.prompt)
                )
                .trim(),
            };
          }
          return { result: true };
        };
        const dest = {};
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'ONU_Disable',
            oltHardVersion,
            view,
          },
          fn,
          me
        );      
        result.msg = `${cmd} successful`;
        result.flag = true;
        resolve(result);  
      } catch (error) {
        reject(error)
      }
    })
  }
  async restoreONU(ponIndex,onuIndex, oltHardVersion,me){
    return new Promise(async(resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag;
      const result = {
        msg: '',
        flag: false,
      };
      const cmd = "restore factory";
      const addr = this.options.ip+":"+this.options.tPort;
      const view ={
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ponIndex,
        onuIndex,
        cmd
      }
      try {
        const fn = function(msg) {
          if (msg.indexOf('Invalid') !== -1) {
            return {
              result: false,
              message: msg
                .substring(
                  msg.indexOf('Invalid:') + 8,
                  msg.indexOf(view.prompt)
                )
                .trim(),
            };
          }
          return { result: true };
        };
        const dest = {};
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'ONU_RESTORE',
            oltHardVersion,
            view,
          },
          fn,
          me
        );      
        result.msg = `${cmd} successful`;
        result.flag = true;
        resolve(result);  
      } catch (error) {
        reject(error)
      }
    })
  }
  async enable(ponIndex,onuIndex, oltHardVersion,me){
    return new Promise(async(resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag;
      const result = {
        msg: '',
        flag: false,
      };
      const cmd = "no shutdown";
      const addr = this.options.ip+":"+this.options.tPort;
      const view ={
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ponIndex,
        onuIndex,
        cmd
      }
      try {
        const fn = function(msg) {
          if (msg.indexOf('Invalid') !== -1) {
            return {
              result: false,
              message: msg
                .substring(
                  msg.indexOf('Invalid:') + 8,
                  msg.indexOf(view.prompt)
                )
                .trim(),
            };
          }
          return { result: true };
        };
        const dest = {};
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'ONU_Disable',
            oltHardVersion,
            view,
          },
          fn,
          me
        );      
        result.msg = `${cmd} successful`;
        result.flag = true;
        resolve(result);  
      } catch (error) {
        reject(error)
      }
    })
  }
  async testLineProfile(oltHardVersion,me){
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_RUNNINGCONFIG',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        let msg = resultArr[0]
        let remoteArr =msg.match(/onu-profile gpon remote[\s\Sa-zA-Z0-9]+?\n!/g)
        let lineArr =  msg.match(/onu-profile gpon line[\s\Sa-zA-Z0-9]+?\n!/g)
        function ParseLine(str){
          let reg = /onu-profile\s+(\w+)\s+line\s+(\w+)/;
          let groups = str.match(reg);
          if(groups&&groups.length===3){
            return {
              type:groups[1],
              name:groups[2]
            }
          }
          return null;
        }
        function ParseTcont(str){
          let reg = /tcont\s+(\d+)\s+profile\s+(\w+)/;
          let groups = str.match(reg);
          if(groups&&groups.length===3){
            return {
              tcont:groups[1],
              dbaProfile:groups[2]
            }
          }
          return null;
        }
        function ParseGem(str){
          let reg=/gemport\s+(\d+)\s+unicast\s+tcont\s+(\d+)/;
          let groups = str.match(reg);
          if(groups&&groups.length===3){
            return {
              gemIndex:groups[1],
              tcont:groups[2]
            }
          }
          return null;
        }
        function ParseSpeed(str){
          let reg=/gemport\s+(\d+)\s+traffic-limit\s+upstream\s+(\w+)\s+downstream\s+(\w+)/;
          let groups = str.match(reg);
          if(groups&&groups.length===4){
            return {
              gemIndex:groups[1],
              upstream:groups[2],
              downstream:groups[3]
            }
          }
        }
        function ParseService(str){
          let reg = /service\s+(\w+).*gemport\s+(\d+)\s+vlan\s+(\w+)/
          let groups = str.match(reg);
          if(groups&&groups.length===4){
            return {
              serviceName:groups[1],
              gemIndex:groups[2],
              vlan:groups[3]
            }
          }
          return null;
        }
        function ParseRemote(str){
          let reg = /onu-profile\s+(\w+)\s+remote\s+(\w+)/;
          let groups = str.match(reg);
          if(groups&&groups.length===3){
            return {
              type:groups[1],
              name:groups[2]
            }
          }
          return null;
        }
        const lineProfiles = [];
        const remoteProfiles = [];
        lineArr.forEach(str=>{
          let lineProfile = {
            id:'',
            name:'',
            type:'',
            tcontArr:[],
            tcontToDba:new Map(),
            gemArr:[],
            gemToTcont:new Map(),
            gemToSpeed:new Map(),
          }
          let arr = str.split('\n');
          if(arr.length>0){
            arr.forEach(item=>{
              //解析line名字
              let info = ParseLine(item);
              if(info){
                lineProfile.name = info.name;
                lineProfile.type = info.type;
              }
              //解析tcont和dbaprofilename的关系
              info = ParseTcont(item)
              if(info){
                lineProfile.tcontArr.push(info.tcont);
                lineProfile.tcontToDba.set(info.tcont,info);
              }
              //解析gemport和tcont的关系
              info = ParseGem(item)
              if(info){
                lineProfile.gemArr.push(info.gemIndex);
                lineProfile.gemToTcont.set(info.gemIndex,info)
              }
              //解析限速
              info = ParseSpeed(item)
              if(info){
                lineProfile.gemToSpeed.set(info.gemIndex,info)
              }
              
            })
          }else{
            return;
          }
          if(lineProfile.name){
            lineProfiles.push(lineProfile)
          }
        })
        remoteArr.forEach(str=>{
          let remoteProfile = {
            name:'',
            type:'',
            service:[],
          }
          let arr = str.split('\n');
          arr.forEach(item=>{
            //解析remote 名字
            let info = ParseRemote(item)
            if(info){
              remoteProfile.name = info.name;
              remoteProfile.type = info.type;
            }
            //解析service名字|gemport序号|vlan序号
            info = ParseService(item)
            if(info){
              remoteProfile.service.push(info)
            }
          })
          if(remoteProfile.name){
            remoteProfiles.push(remoteProfile)
          }
        })
        resolve(lineProfiles)
      } catch (error) {
        reject(error);
      }
    });
  }
  async getOnuListMsg(onuList,oltHardVersion,me){
    let arr = []
    for(var i in onuList){
      let oltport = onuList[i].port.replace('onu','olt')
      if(arr.indexOf(oltport.split(':')[0]) == -1){
        arr.push(oltport.split(':')[0])
      }
    }
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GET_RUNNINGCONFIG',
            oltHardVersion,
            view,
          },
          null,
          me
        );
        let resultArray = []
        let msg =  resultArr[0].split('!')
        for(var i = 0;i<msg.length;i++){
          msg[i].replace(/\u0008/g, '').replace(/\s*--More--\s*/g, '\n')
          if(msg[i].indexOf('gpon-olt_1')!= -1){
            let result = msg[i].split('\n')
            result.shift()
            for(var j=0;j<result.length;j++){
              let port = result[0].replace('interface','').replace('olt','onu').trim()
              if(result[j].indexOf('sn') != -1 ||result[j].indexOf('pw') != -1){
                let a = result[j].trim().replace(/\u0008/g, '').replace(/\s*--More--\s*/g, '').replace(/\s{1,}/g,'|').split('|')
                let state = ""
                if(onuList[port+":"+a[1].trim()].state == "LOS"){
                  state = "LOS"
                }else if(onuList[port+":"+a[1].trim()].state == "OffLine"){
                  state = "OffLine"
                }else if (onuList[port+":"+a[1].trim()].state == "working"){
                  state = "OnLine"
                }else if(onuList[port+":"+a[1].trim()].state == "DyingGasp"){
                  state = "DyingGasp"
                }else{
                  state = "N/A"
                }
                resultArray.push({
                  PONindex: port,
                  ONUindex: a[1].trim(),
                  onlyindex:port+":"+a[1].trim(),
                  sn:a[5].trim(),
                  status:state,
                  number: a[1].trim(),
                  slot: port.split('/')[1].trim(),
                  port: port.split('/')[2].trim()
                })
              }
            }
          }
        }
        resolve(resultArray)
      } catch (error) {
        reject(error);
      }
    });
  }
  async setCatvState(oltHardVersion,onuResult,catvstate,me){
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      let cmd
      if(catvstate == "true"){
        cmd = "unlock"
      }else if(catvstate == "false"){
        cmd = "lock"
      }
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        onuResult,
        cmd
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_CATVSTATE',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    })
  }
  async updateEthState(oltHardVersion,params,me){
    return new Promise(async (resolve, reject) => {
      me.proxyFlag = this.options.proxyFlag;
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ...params
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'SET_ETHSTATE',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true);
      } catch (error) {
        reject(error);
      }
    })
  }
  async getWANInfo(oltHardVersion,onuAddress,me){
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        onuAddress,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'WANINFO',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        if(resultArr.length===2){
          let msg = resultArr[0]||"";
          if(!msg){
            reject("no response return")
          }
          if(msg.indexOf('No relate information to show')!==-1){
            return resolve('No relate information to show');
          }
          let parseReg = /(\s*(.*):\s*(.*)\n)/ig
          let arr =strToEachType(msg,/WAN in?dex/i);
          let resultArray = parseOnuWan(arr,parseReg);
          let wanStr = resultArr[1]||"";
          if(!wanStr){
            resolve("show onu running config -> no response return")
          }
          let rows = wanStr.split('\n');
          let wanReg0 = /wan-ip\s*(\w+)\s*mode\s*(\w+)\s*.*/i;
          let wanReg = /wan-ip\s*(\w+)\s*mode\s*(\w+)\s*.*vlan-profile(.*)host.*/i;
          let wans = rows.map((item,index)=>{
            let group = item.match(wanReg0)
            if(group){
              let [s,wanIndex,mode] = group;
              if(mode=="static"||item.indexOf('pppoe')!=-1){
                return item+rows[index+1];//因为static太长了，跨行了，所以需要把第二行也接入进来
              }else{
                return item;
              }
            }else{
              return "none";
            }
          })
          
          wans.forEach((str,i)=>{
            let group = str.match(wanReg);
            if(group){
              let [s,wanIndex,mode,vlanProfile] = group;
              let wanObj = resultArray.find(element=>element.id==wanIndex);
              wanObj["vlanProfile"] = vlanProfile.trim();
              switch(mode){
                  case "dhcp":                    
                    break;
                  case "pppoe":
                    wanObj["pppoeUsername"] = str.substring(str.indexOf('username')+8,str.indexOf("password")).trim();
                    wanObj["pppoePassword"] = str.substring(str.indexOf('password')+8,str.indexOf("vlan-profile")).trim();
                    break;
                  case "static":
                    wanObj["ipProfile"] = str.substring(str.indexOf('ip-profile')+10,str.indexOf("ip-address")).trim();
                    wanObj["ipAddress"] = str.substring(str.indexOf('ip-address')+10,str.indexOf("mask")).trim();
                    wanObj["mask"] = str.substring(str.indexOf('mask')+4,str.indexOf("vlan-profile")).trim();
                    break;
              }
            }
          })
          resolve(resultArray);
        }else{
          reject("命令返回的数据集不满足期待")
        }
      } catch (error) {
        reject(error);
      }
    })
  }
  async getVOIPInfo(oltHardVersion,onuAddress,me){
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        onuAddress,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'VOIPINFO',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        let msg = resultArr[0]||"";
        if(!msg){
          reject("no response return")
        }
  //       let arr = msg.split('WAN idex').map(item=>'WAN idex'+item);
  //       let resultArray = [];
  // //       voip protocol sip
  // // voip-ip mode dhcp vlan-profile vlan100 host 2
  //       arr.forEach(item=>{
  //         let rows = item.split('\n');
          
  //         resultArray.push(obj);
  //       })
        let testReg = /voip-ip.*mode\s*(\w+)\s*.*/i;
        let lines = msg.split('\n')
        let rows = lines.map((item,index)=>{
          let group = item.match(testReg)
          if(group){
            let [s,mode] = group;
            if(mode=="static"||item.indexOf('pppoe')!=-1){
              return item+lines[index+1];//因为static\pppoe太长了，跨行了，所以需要把第二行也接入进来
            }else{
              return item;
            }
          }else if(item.indexOf('voip')!=-1||item.indexOf('sip-service')!==-1){
            return item;
          }else{
            return "none";
          }
        }).filter(item=>item!=="none");
        
        let obj = {
          enable:false,
          name:"",
          mode:"",
          vlanProfile:"",
          username:"",
          password:"",
          host:"",
        }
        //voip-ip mode dhcp vlan-profile vlan100 host 2
        //sip-service pots_0/1 profile LABTEST userid 1002 username 1002 password 1002
        let reg = /voip-ip\s*mode\s*(\w+)\s*vlan-profile\s*(.+)\s*host\s*(\w+)\s*/i
        let reg2 = /sip-service\s*(.*)\s*profile\s*(.*)\s*userid\s*(.*)\s*username\s*(.*)\s*password\s*(.*)\s*/i
        let staticReg = /voip-ip.*ip-profile\s*(\w+)\s*ip\s*(.*)\s*mask\s*(.*)\s*vlan-profile(.*)host\s*(\w+)\s*/i
        let pppoeReg = /voip-ip.*username\s*(\w+)\s*password\s*(.*)\s*vlan-profile(.*)host\s*(\w+)\s*/i
        for(let row of rows){
          if(row&&/voip protocol/ig.test(row)){
            obj.enable = true;
            continue
          }
          if(row&&reg.test(row)){
            let groups = row.match(reg);
            if(groups){
              let [str,s1,s2,s3] = groups;
              obj.mode = s1;
              obj.vlanProfile = s2;
              obj.host = s3
            }
            continue
          }
          if(row&&reg2.test(row)){
            let groups = row.match(reg2);
            if(groups){
              let [str,s1,s2,s3,s4,s5] = groups;
              obj.pots = s1.trim();
              obj.sipProfile = s2.trim();
              obj.userID = s3.trim();
              obj.sipUsername = s4.trim();
              obj.sipPassword = s5.trim();
            }
            continue
          }
          if(row&&pppoeReg.test(row)){
            let groups = row.match(pppoeReg);
            if(groups){
              let [str,s1,s2,s3,s4] = groups;
              obj.pppoeUsername = s1.trim();
              obj.pppoePassword = s2.trim();
              obj.vlanProfile = s3.trim();
              obj.host = s4.trim();
              obj.mode="pppoe";
            }
            continue
          }
          if(row&&staticReg.test(row)){
            let groups = row.match(staticReg);
            if(groups){
              let [str,s1,s2,s3,s4,s5] = groups;
              obj.ipProfile = s1.trim();
              obj.ipAddress = s2.trim();
              obj.mask = s3.trim();
              obj.vlanProfile = s4.trim();
              obj.host = s5.trim();
              obj.mode="static";
            }
            continue
          }
        }
        resolve(obj);
      } catch (error) {
        reject(error);
      }
    })
  }
  async getETH(oltHardVersion,onuAddress,me){
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        onuAddress,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GETETH',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        // parse return info
        if(resultArr.length===2){
          let [eths,configs] = resultArr;
          let ethVlanReg = /vlan port (eth_\d\/\d+).*mode\s+(\w+)\s?vlan\s+(\w+)\s?$/i;
          let parseEthReg = /(\s*(.*):\s*(.*)\n)/ig
          let configArr = configs.split('\n').filter(item=>ethVlanReg.test(item));
          let ethArr = strToEachType(eths,'Interface');
          let result = parseEth(ethArr,parseEthReg);
          for(let str of configArr){
            let group = str.match(ethVlanReg);
            if(group){
              let [str,s1,s2,s3] = group;
              result[s1]["mode"] = s2;
              result[s1]["vlan"] = s3;
            }
          }
          let res = [];
          for(let i in result){
            res.push(result[i])
          }
          resolve(res)
        }else{
          reject("命令返回的数据集不满足期待")
        }
      } catch (error) {
        reject(error)
      }
    })
  }
  async getCATVState(oltHardVersion,onuAddress,me){
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        onuAddress,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GETCATVSTATE',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        //parse return info
        if(resultArr.length==1){
          let str = resultArr[0];
          let strArr = str.split('\n').filter(item=>item.indexOf('config')==-1);
          let lastLine = strArr[strArr.length-1];
          let arr = lastLine.split(/\s+/);
          if(arr&&arr.length>2){
            resolve(arr[1].trim())
          }
        }else{
          reject("命令返回的数据集不满足期待")
        }
      } catch (error) {
        reject(error)
      }
    })
  }
  async refreshOltProfile(oltHardVersion,me){
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
      };
      try {
        const resultArr = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'GETOLTPROFILE',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        //parse return info
        let parseReg = /(\s*(.*):\s*(.*)\n)/ig
        if(resultArr.length==3){
          let [vlanStr,ipStr,sipStr] = resultArr;
          let vlanResArr = strToEachType(vlanStr,'Profile name');
          let vlanProfiles=parseOltProfile(vlanResArr,parseReg,'vlan-profile');
          
          let ipResArr = strToEachType(ipStr,'Profile name');
          let ipProfiles = parseOltProfile(ipResArr,parseReg,'ip-profile');
          
          let sipResArr =strToEachType(sipStr,'Profile name');
          let sipProfiles=parseOltProfile(sipResArr,parseReg,'sip-profile');
          resolve(vlanProfiles.concat(ipProfiles).concat(sipProfiles));
        }else{
          reject("命令返回的数据集不满足期待")
        }
      } catch (error) {
        reject(error)
      }
    })
  }
  async createOltprofile(oltHardVersion,oltProfile,me) {
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        type:oltProfile.type,
        mode:oltProfile.tagMode,
        name:oltProfile.profileName,
        cvlan:oltProfile.cVlan,
        svlan:oltProfile.sVlan,
        gateway:oltProfile.gateway,
        proxy:oltProfile.proxyServer,
        registrar:oltProfile.registrar,
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CREATEOLTPROFILE',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true)
      } catch (error) {
        reject(error)
      }
    })
  }

  async deleteOltProfile(oltHardVersion,oltProfile,me) {
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        type:oltProfile.type==='vlan-profile'?'vlan':oltProfile.type==='ip-profile'?'ip':'sip',
        name:oltProfile.profileName,
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETEOLTPROFILE',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true)
      } catch (error) {
        reject(error)
      }
    })
  }

  async createWan(oltHardVersion,wanObj,me){
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ...wanObj
      };
      try {
        const fn = function (msg) {
          if (msg.indexOf('%Code') != -1) {
            return {
              result: false,
              message: msg
            };
          } 
          return {
            result: true
          };
        };
        let res = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CREATEWAN',
            oltHardVersion: oltHardVersion,
            view,
          },
          fn,
          me
        );
        if(res.length>0){
          resolve({
            flag:false,
            message:res[0]
          })
        }
        resolve({flag:true})
      } catch (error) {
        reject(error)
      }
    })
  }
  async deleteWan(oltHardVersion,wanObj,me){
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ...wanObj
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETEWAN',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true)
      } catch (error) {
        reject(error)
      }
    })
  }

  async createOrUpdateVOIP(oltHardVersion,voipObj,me){
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ...voipObj
      };
      try {
        const fn = function (msg) {
          if (msg.indexOf('%Code') != -1) {
            return {
              result: false,
              message: msg
            };
          } 
          return {
            result: true
          };
        };
        let res = await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'CREATEVOIP',
            oltHardVersion: oltHardVersion,
            view,
          },
          fn,
          me
        );
        if(res.length>0){
          resolve({
            flag:false,
            message:res[0]
          })
        }
        resolve({flag:true})
      } catch (error) {
        reject(error)
      }
    })
  }
  async deleteVoip(oltHardVersion,voipObj,me){
    return new Promise(async (resolve,reject)=>{
      me.proxyFlag = this.options.proxyFlag; //proxyFlag代表是否走穿透
      const addr = this.options.ip + ':' + this.options.tPort;
      const view = {
        username: this.options.RZUsername,
        password: this.options.RZPassword,
        prompt: this.options.systemName,
        ManagementPassword: this.options.managementPassword,
        ...voipObj
      };
      try {
        await common.run_EX(
          addr,
          {
            oltType: 'ZTE',
            mountPoint: 'DELETEVOIP',
            oltHardVersion: oltHardVersion,
            view,
          },
          null,
          me
        );
        resolve(true)
      } catch (error) {
        reject(error)
      }
    })
  }
}
function getNames(str) {
  // if(str.indexOf())
  const arr = str.split(/-{4,}/g);
  if (arr && arr.length > 1) {
    const str1 = arr[1];
    const arr1 = str1.split('\n');
    const result = arr1.map(item => {
      if (item.indexOf('More') !== -1) {
        return item.replace(/\s*--More.*(\u0008)/g, '').trim();
      }
      return item.trim();
    });
    return result;
  }
  return null;
}
function getArr(untaglist) {
  const arr = [];
  untaglist.forEach(item => {
    if (item.indexOf('gei') != -1) {
      const msg = item.split('/')[2];
      if (msg.indexOf(',') != -1) {
        const msg1 = msg.split(',');
        msg1.forEach(result => {
          if (result.indexOf('-') != -1) {
            const resultstart = result.split('-')[0];
            const resultstop = result.split('-')[1];
            for (let i = resultstart; i <= resultstop; i++) {
              arr.push(
                (item.split('/')[0] + '/' + item.split('/')[1] + '/' + i).trim()
              );
            }
          } else {
            arr.push(
              (
                item.split('/')[0] +
                '/' +
                item.split('/')[1] +
                '/' +
                result
              ).trim()
            );
          }
        });
      } else if (msg.indexOf('-') != -1) {
        const untagstart = msg.split('-')[0];
        const untagstop = msg.split('-')[1];
        for (let j = untagstart; j <= untagstop; j++) {
          arr.push(
            (item.split('/')[0] + '/' + item.split('/')[1] + '/' + j).trim()
          );
        }
      } else {
        arr.push(
          (item.split('/')[0] + '/' + item.split('/')[1] + '/' + msg).trim()
        );
      }
    }
  });
  return arr;
}

module.exports = ZTEOLT;
